import axios, { AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios'
import { ElMessage } from 'element-plus'
import { useUserStore } from '@/store/modules/user'
import EmojiText from '../emojo'
import { HOME_PAGE, router } from '@/router'
import { UserService } from '@/api/userApi/usersApi'

const axiosInstance = axios.create({
  timeout: 15000, // 请求超时时间(毫秒)
  baseURL: import.meta.env.VITE_API_URL, // API地址
  withCredentials: true, // 异步请求携带cookie
  transformRequest: [
    (data) => {
      if (data instanceof FormData) {
        return data // FormData 不需要转换
      }
      return JSON.stringify(data) // 其他数据转换为 JSON
    }
  ],
  validateStatus: (status) => status >= 200 && status < 300, // 只接受 2xx 的状态码
  headers: {
    get: { 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8' },
    post: {}
  }
  /*  transformResponse: [
      (data, headers) => {
        const contentType = headers?.['content-type']
        if (contentType && contentType.includes('application/json')) {
          try {
            if (!(data instanceof FormData)) {
              return JSON.stringify(data)
            }
          } catch {
            return data
          }
        }
        return data
      }
    ]*/
})

// 请求拦截器
axiosInstance.interceptors.request.use(
  (request: InternalAxiosRequestConfig) => {
    // console.log('请求头:', request.headers)

    const { accessToken } = useUserStore()

    // 如果 token 存在，则设置请求头
    if (accessToken) {
      request.headers.set('Authorization', 'Bearer ' + accessToken)
    }

    // 对于 FormData 数据，删除 Content-Type 让浏览器自动处理
    if (request.data instanceof FormData) {
      // console.log('请求数据:', request.data)
      delete request.headers['Content-Type'] // 删除 Content-Type 让浏览器自动设置
    }

    return request // 返回修改后的配置
  },
  (error) => {
    ElMessage.error(`服务器异常！ ${EmojiText[500]}`)
    return Promise.reject(error)
  }
)

// 响应拦截器
axiosInstance.interceptors.response.use(
  (response: AxiosResponse) => {
    const { refreshToken } = useUserStore()
    const userStore = useUserStore()

    if (response.status === 200) {
      if (response.data.code === 401 && response.data.message === '无效的 Token') {
        if (refreshToken) {
          UserService.refreshToken(refreshToken).then((res) => {
            if (res.code === 200) {
              userStore.setToken(res.data)
              router.push(HOME_PAGE)
            } else {
              ElMessage.error(`'当前登录已过期，请重新登录' ${EmojiText[500]}`)
              router.push('/login')
            }
          })
        } else {
          ElMessage.error(`当前登录已过期，请重新登录 ${EmojiText[500]}`)
          router.push('/login')
        }

        return response
      } else {
        return response
      }
    } else {
      ElMessage.error(`服务器异常！ ${EmojiText[500]}`)
      return Promise.reject(response)
    }
  },
  (error) => {
    console.log('请求拦截', error.response.code)
    if (error.response) {
      // 请求已发出，但服务器响应的状态码不在 2xx 范围内
    }
    if (axios.isCancel(error)) {
      console.log('repeated request: ' + error.message)
    } else {
      const errorMessage = error.response?.data.message
      ElMessage.error(
        errorMessage
          ? `${errorMessage} ${EmojiText[500]}`
          : `请求超时或服务器异常！${EmojiText[500]}`
      )
    }
    return Promise.reject(error)
  }
)

// 请求
async function request<T = any>(config: AxiosRequestConfig): Promise<T> {
  // 对 POST | PUT 请求特殊处理
  if (config.method?.toUpperCase() === 'POST' || config.method?.toUpperCase() === 'PUT') {
    // 如果已经有 data，则保留原有的 data
    if (config.params && !config.data) {
      config.data = config.params
      config.params = undefined // 使用 undefined 而不是空对象
    }
  }

  try {
    const res = await axiosInstance.request<T>({ ...config })
    return res.data
  } catch (e) {
    if (axios.isAxiosError(e)) {
      const errorMessage = e.response?.data?.message || '请求失败'
      ElMessage.error(`${errorMessage} ${EmojiText[500]}`)
    }
    throw e // 抛出错误让调用者处理
  }
}

// API 方法集合
const api = {
  get<T>(config: AxiosRequestConfig): Promise<T> {
    return request({ ...config, method: 'GET' }) // GET 请求
  },
  post<T>(config: AxiosRequestConfig): Promise<T> {
    return request({ ...config, method: 'POST' }) // POST 请求
  },
  put<T>(config: AxiosRequestConfig): Promise<T> {
    return request({ ...config, method: 'PUT' }) // PUT 请求
  },
  del<T>(config: AxiosRequestConfig): Promise<T> {
    return request({ ...config, method: 'DELETE' }) // DELETE 请求
  }
}

export default api
